package com.ddstation.onsitelaw.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ddstation.common.util.IdGenerateUtil;
import com.ddstation.onsitelaw.entity.DtHealthManageInstitutionEntity;
import com.ddstation.onsitelaw.entity.DtSupervisorEnforcementEntity;
import com.ddstation.onsitelaw.entity.auditentity.DdDoctorEntity;
import com.ddstation.onsitelaw.entity.auditentity.DtHealthDataOutpatientMedicalEntity;
import com.ddstation.onsitelaw.entity.auditentity.DtHealthDataWestPrescriptionEntity;
import com.ddstation.onsitelaw.entity.auditentity.DtInvsViolationManageEntity;
import com.ddstation.onsitelaw.model.*;
import com.ddstation.onsitelaw.service.*;
import com.ddstation.onsitelaw.utils.*;
import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.inject.Inject;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author 陆青龙
 */
@Controller
public class takePictureController {

    private static final Logger logger = LoggerFactory.getLogger(takePictureController.class);
    @Inject
    private DtHealthManageInstitutionService dtHealthManageInstitutionService;

    @Inject
    private OutpatientService outpatientService;

    @Inject
    private PrescriptionService prescriptionService;


    @Inject
    private AuditPrescriptionService auditPrescriptionService;

    @Inject
    private ClinicAuditService clinicAuditService;

    /**
     * 跳转拍照页面
     */
    @RequestMapping(value = "takePicture")
    String takePicture(HttpSession session, Model model) {
        Map<String, Object> map = new HashMap<>();
        map.put("errCode", 0);
        map.put("errMsg", "服务器繁忙，请稍后再试。");
        //获取session登录信息
        AccountModel account = (AccountModel) session.getAttribute("account");
        if (account == null || account.getSupervisorId() == null) {
            map.put("errCode", -1);
            return "app/takePicture";
        }
        List<String> healthManageInstitutionIds = null;
        if (account.getRoleId() == 1) {
            List<DtHealthManageInstitutionEntity> healthManageList = account.getDtHealthManageInstitutionEntityList();
            healthManageInstitutionIds = healthManageList.stream().map(i -> i.getId()).collect(Collectors.toList());
        }
        if (account.getRoleId() == 2) {
            List<DtSupervisorEnforcementEntity> supervisorEnforcements = account.getEnforcementList();
            healthManageInstitutionIds = supervisorEnforcements.stream().map(i -> i.getHealthManageId()).collect(Collectors.toList());
        }
        HashMap paramMap = new HashMap();
        paramMap.put("institutionIdList", healthManageInstitutionIds);
        paramMap.put("pageNum", 1);
        paramMap.put("pageSize", 10000);
        PageResult pageResult = dtHealthManageInstitutionService.getHealthManageList(paramMap);
        model.addAttribute("selectHealthManageList", pageResult.getRows());
        return "app/takePicture";
    }


    /**
     * 上传处方
     */
    @RequestMapping(value = "takePicture/uploadPrescription")
    @ResponseBody
    Map<String, Object> uploadPrescription(HttpSession session, @RequestParam("files") MultipartFile[] files, @RequestParam("healthManageId") String healthManageId, @RequestParam("doctorId") String doctorId) throws Exception {


        Map<String, Object> map = new HashMap<>();
        map.put("errCode", 0);
        map.put("errMsg", "已提交审核！");


        if (ObjectUtils.isEmpty(files)) {
            map.put("errCode", -1);
            map.put("errMsg", "请上传处方图片！");
            return map;
        }


        //获取session登录信息
        AccountModel account = (AccountModel) session.getAttribute("account");

        if (account == null || account.getSupervisorId() == null) {
            map.put("errCode", -1);
            map.put("errMsg", "服务器繁忙，请稍后再试。");
            return map;
        }

        // 获取机构所有处方模板
        List<DtPrescriptionTemplateManageModel> prescriptionTemplates = dtHealthManageInstitutionService.selectPrescriptionTemplate(healthManageId, null);
        if (ObjectUtils.isEmpty(prescriptionTemplates)) {
            map.put("errCode", -1);
            map.put("errMsg", "该机构下未检测到类似处方模板，请点击【上传模板】！");
            return map;
        }


        //MultipartFile转File
        List<File> fileList = new ArrayList<>();
        for (MultipartFile file : files) {
            fileList.add(MultipartFileToFile.multipartFileToFile(file));
        }

        List<String> templateSigns = prescriptionTemplates.stream().map(i -> i.getTemplateSign()).collect(Collectors.toList());
        ThreadPoolHelper.executeTask(() -> {
            try {
                intelligentAuditing(fileList, templateSigns, healthManageId, doctorId, account);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        return map;
    }

    private Float getOnceDose(String str) {
        String str2 = "";
        if (str != null && !"".equals(str)) {
            boolean ss = false;
            for (int i = 0; i < str.length(); i++) {

                if (str.charAt(i) >= 48 && str.charAt(i) <= 57) {
                    ss = true;
                    str2 += str.charAt(i);
                } else {
                    if (ss) {
                        break;
                    }
                }
            }
        }

        return Float.valueOf(str2);
    }

    /**
     * 智能审核处方
     *
     * @param files
     * @param templateSigns
     * @param institutionId
     * @return
     * @throws IOException
     */
    void intelligentAuditing(List<File> files, List<String> templateSigns, String institutionId, String doctorId, AccountModel account) throws IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String today = sdf.format(new Date());
        //保存路径：prescription/yyyyMMdd/机构id/图片文件
        String prescriptionDir = "prescription/" + today + "/" + institutionId;

        for (File localFile : files) {

            long size = localFile.length();//单位B
            if (size >= (1024 * 1024 * 4)) {//大于4M进行压缩
                //压缩文件
                Thumbnails.of(localFile)
                        .scale(1f)//指定图片的大小，值在0到1之间，1f就是原图大小，0.5就是原图的一半大小
                        .outputQuality(0.5f)//图片的质量，值也是在0到1，越接近于1质量越好，越接近于0质量越差
                        .toFile(localFile);
            }
            String fileName = localFile.getName();
            // 阿里云上传 object key
            String ossKey = prescriptionDir + "/" + fileName.substring(0, fileName.lastIndexOf(".")) + fileName.substring(fileName.lastIndexOf("."));
            // 上传 阿里云 oss
            AliCloudOssUtil.putOSSObject(null, ossKey, localFile);
            //百度识别图片文字，返回识别文字
            boolean isFlg = true;
            for (String templateSign : templateSigns) {
                String result = BaiduImgApiUtil.getPictureText(localFile.getPath(), templateSign);
                JSONObject resObject = JSONObject.parseObject(result);
                if ("0".equals(resObject.getString("error_code"))) {
                    isFlg = false;
                    //json字符串转object
                    OutpatientMedicalModel outpatientMedicalModel = jsonStrToObject(result);
                    //更新病历表
                    outpatientMedicalModel.setInstitutionId(institutionId);
                    outpatientMedicalModel.setDoctorId(doctorId);
                    DtHealthDataOutpatientMedicalEntity medical = outpatientService.addMedical(outpatientMedicalModel);
                    //更新处方表
                    PrescriptionModel model = new PrescriptionModel();
                    model.setInstitutionId(institutionId);
                    model.setMedicalId(medical.getId());
                    model.setUserName(outpatientMedicalModel.getName());


                    List<DrugItems> itemsList = new ArrayList<>();
                    List<DtHealthDataWestPrescriptionEntity> prescriptions = new ArrayList<>();

                    if (!StringUtils.isEmpty(outpatientMedicalModel.getDrugName())) {
                        DrugItems item = new DrugItems();
                        item.setItemName(outpatientMedicalModel.getDrugName());
                        item.setGroupNo(1);
                        itemsList.add(item);

                        DtHealthDataWestPrescriptionEntity entity = new DtHealthDataWestPrescriptionEntity();
                        entity.setItemName(outpatientMedicalModel.getDrugName().replaceAll("[^\u4E00-\u9FA5]", ""));
                        //entity.setOnceDose(getOnceDose(outpatientMedicalModel.getUseText()));
                        entity.setOnceDoseUnitType(0);
                        prescriptions.add(entity);

                    }
                    if (!StringUtils.isEmpty(outpatientMedicalModel.getDrugName1())) {

                        DrugItems item = new DrugItems();
                        item.setItemName(outpatientMedicalModel.getDrugName1());
                        item.setGroupNo(2);
                        itemsList.add(item);

                        DtHealthDataWestPrescriptionEntity entity = new DtHealthDataWestPrescriptionEntity();
                        entity.setItemName(outpatientMedicalModel.getDrugName1().replaceAll("[^\u4E00-\u9FA5]", ""));
                       // entity.setOnceDose(getOnceDose(outpatientMedicalModel.getUseText1()));
                        entity.setOnceDoseUnitType(0);
                        prescriptions.add(entity);

                    }
                    if (!StringUtils.isEmpty(outpatientMedicalModel.getDrugName2())) {
                        DrugItems item = new DrugItems();
                        item.setItemName(outpatientMedicalModel.getDrugName2());
                        item.setGroupNo(3);
                        itemsList.add(item);

                        DtHealthDataWestPrescriptionEntity entity = new DtHealthDataWestPrescriptionEntity();
                        entity.setItemName(outpatientMedicalModel.getDrugName2().replaceAll("[^\u4E00-\u9FA5]", ""));
                       // entity.setOnceDose(getOnceDose(outpatientMedicalModel.getUseText2()));
                        entity.setOnceDoseUnitType(0);
                        prescriptions.add(entity);
                    }
                    if (!StringUtils.isEmpty(outpatientMedicalModel.getDrugName3())) {
                        DrugItems item = new DrugItems();
                        item.setItemName(outpatientMedicalModel.getDrugName3());
                        item.setGroupNo(4);
                        itemsList.add(item);

                        DtHealthDataWestPrescriptionEntity entity = new DtHealthDataWestPrescriptionEntity();
                        entity.setItemName(outpatientMedicalModel.getDrugName3().replaceAll("[^\u4E00-\u9FA5]", ""));
                        //entity.setOnceDose(getOnceDose(outpatientMedicalModel.getUseText3()));
                        entity.setOnceDoseUnitType(0);
                        prescriptions.add(entity);
                    }
                    if (!StringUtils.isEmpty(outpatientMedicalModel.getDrugName4())) {
                        DrugItems item = new DrugItems();
                        item.setItemName(outpatientMedicalModel.getDrugName4());
                        item.setGroupNo(5);
                        itemsList.add(item);

                        DtHealthDataWestPrescriptionEntity entity = new DtHealthDataWestPrescriptionEntity();
                        entity.setItemName(outpatientMedicalModel.getDrugName4().replaceAll("[^\u4E00-\u9FA5]", ""));
                      //  entity.setOnceDose(getOnceDose(outpatientMedicalModel.getUseText4()));
                        entity.setOnceDoseUnitType(0);
                        prescriptions.add(entity);
                    }
                    if (!StringUtils.isEmpty(outpatientMedicalModel.getDrugName5())) {
                        DrugItems item = new DrugItems();
                        item.setItemName(outpatientMedicalModel.getDrugName5());
                        item.setGroupNo(6);
                        itemsList.add(item);

                        DtHealthDataWestPrescriptionEntity entity = new DtHealthDataWestPrescriptionEntity();
                        entity.setItemName(outpatientMedicalModel.getDrugName5().replaceAll("[^\u4E00-\u9FA5]", ""));
                      //  entity.setOnceDose(getOnceDose(outpatientMedicalModel.getUseText5()));
                        entity.setOnceDoseUnitType(0);
                        prescriptions.add(entity);
                    }
                    model.setItemsList(itemsList);
                    try {
                        String prescriptionId = prescriptionService.addPrescription(model);
                        prescriptions.forEach(item -> {
                            item.setPrescriptionId(prescriptionId);
                        });
                        AuditPrescriptionModel auditModel = new AuditPrescriptionModel();
                        DdDoctorEntity doctor = dtHealthManageInstitutionService.selectDoctorInfoByKey(doctorId);

                        List<DtInvsViolationManageEntity> outpatientMedicalViolations = clinicAuditService.auditOutpatientMedical(medical, institutionId, doctor);

                        List<DtInvsViolationManageEntity> prescriptionsViolations = clinicAuditService.auditPrescriptions(medical, institutionId, doctor, prescriptions);
                        //接口返回审核结果，1合规，2违规
                        auditModel.setAuditResult(1);
                        if (!ObjectUtils.isEmpty(prescriptionsViolations) || !ObjectUtils.isEmpty(outpatientMedicalViolations)) {
                            auditModel.setAuditResult(2);
                        }
                        //生成审核数据
                        auditModel.setInvsInstitutionId(account.getInstitutionId());
                        auditModel.setInstitutionId(institutionId);
                        auditModel.setMedicalId(medical.getId());
                        auditModel.setPrescriptionId(prescriptionId);
                        auditModel.setPrescriptionPicUrl(ossKey);
                        auditModel.setUploaderId(account.getSupervisorId());
                        auditModel.setUploaderName(account.getLoginUser());
                        auditModel.setUploadTm(new Date());
                        auditModel.setAuditTm(new Date());
                        auditModel.setViolateDt(outpatientMedicalModel.getViolateDt());
                        auditModel.setAutoAudit(1);
                        auditPrescriptionService.insertAuditPrescription(auditModel);
                    } catch (Exception e) {
                        isFlg = true;
                        logger.info(e.getMessage());
                    }

                    break;
                }
            }
            if (isFlg) {
                AuditPrescriptionModel auditModel = new AuditPrescriptionModel();
                auditModel.setInvsInstitutionId(account.getInstitutionId());
                auditModel.setInstitutionId(institutionId);
                auditModel.setMedicalId(IdGenerateUtil.idGenerateFromTime("04"));
                auditModel.setPrescriptionId(IdGenerateUtil.idGenerateFromTime("04"));
                auditModel.setPrescriptionPicUrl(ossKey);
                auditModel.setUploaderId(account.getSupervisorId());
                auditModel.setUploaderName(account.getLoginUser());
                auditModel.setUploadTm(new Date());
                auditModel.setAutoAudit(2);
                auditPrescriptionService.insertAuditPrescription(auditModel);
            }
        }
    }


    /**
     * json字符串转object
     *
     * @param result
     * @return
     */
    OutpatientMedicalModel jsonStrToObject(String result) {
        //将json字符串转换成jsonObject对象
        JSONObject resObj = JSON.parseObject(result);
        JSONArray retJSONArray = resObj.getJSONObject("data").getJSONArray("ret");
        Map<String, Object> retMap = new HashMap<>();
        for (int i = 0; i < retJSONArray.size(); i++) {
            retMap.put(JSON.parseObject(retJSONArray.get(i).toString()).getString("word_name"), JSON.parseObject(retJSONArray.get(i).toString()).getString("word"));
        }
        //Map转Object
        return JSONObject.parseObject(JSONObject.toJSONString(retMap), OutpatientMedicalModel.class);
    }


    @RequestMapping("takePicture/getDoctorByInstitutionId")
    @ResponseBody
    Map<String, Object> getDoctorByInstitutionId(HttpSession session, @RequestParam String institutionId) {
        Map<String, Object> map = new HashMap<>();
        map.put("errCode", 0);
        map.put("errMsg", "服务器繁忙，请稍后再试。");
        //获取session登录信息
        AccountModel account = (AccountModel) session.getAttribute("account");
        if (account == null || account.getSupervisorId() == null) {
            map.put("errCode", -1);
            return map;
        }
        List<DoctorModel> doctorList = dtHealthManageInstitutionService.getDoctorByInstitutionId(institutionId);
        map.put("errCode", 1);
        map.put("doctorList", doctorList);
        map.put("errMsg", "服务器繁忙，请稍后再试。");
        return map;
    }


    /**
     * 上传处方
     */
    @RequestMapping(value = "takePicture/appSavePrescriptionTemplate")
    @ResponseBody
    Map<String, Object> appSavePrescriptionTemplate(HttpSession session, @RequestParam("file") MultipartFile file, @RequestParam("healthManageId") String healthManageId, @RequestParam("templateName") String templateName, @RequestParam("flg") String flg) throws Exception {
        Map<String, Object> map = new HashMap<>();
        map.put("errCode", 0);
        map.put("errMsg", "处方模板上传成功！");
        if (ObjectUtils.isEmpty(file)) {
            map.put("errCode", -1);
            map.put("errMsg", "请上传一张处方模板");
        }
        //获取session登录信息
        AccountModel account = (AccountModel) session.getAttribute("account");
        if (account == null || account.getSupervisorId() == null) {
            map.put("errCode", -1);
            map.put("errMsg", "服务器繁忙，请稍后再试。");
            return map;
        }
        if ("0".equals(flg)) {
            List<DtPrescriptionTemplateManageModel> templates = dtHealthManageInstitutionService.selectPrescriptionTemplate(healthManageId, "-1");
            List<String> templateNames = templates.stream().map(i -> i.getName()).collect(Collectors.toList());

            if (!ObjectUtils.isEmpty(templateNames) && templateNames.contains(templateName)) {
                map.put("errCode", -1);
                map.put("errMsg", "此模板之前已提交，尽快联系技术人员配置！");
                return map;
            }

            if (!ObjectUtils.isEmpty(templateNames)) {
                map.put("errCode", -2);
                map.put("errMsg", "该机构存在未配置模板:" + String.join(",", templateNames) + "。确认继续上传模板吗？");
                return map;
            }
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String today = sdf.format(new Date());
        //保存路径：prescription/yyyyMMdd/机构id/图片文件
        String prescriptionDir = "prescriptionTemplate/" + today + "/" + account.getInstitutionId();
        File localFile = MultipartFileToFile.multipartFileToFile(file);

        //图片大于4M进行压缩
        long size = localFile.length();//单位B
        if (size >= (1024 * 1024 * 4)) {//大于4M进行压缩
            //压缩文件
            Thumbnails.of(localFile)
                    .scale(1f)//指定图片的大小，值在0到1之间，1f就是原图大小，0.5就是原图的一半大小
                    .outputQuality(0.5f)//图片的质量，值也是在0到1，越接近于1质量越好，越接近于0质量越差
                    .toFile(localFile);
        }
        // 阿里云上传 object key
        String fileName = localFile.getName();
        String ossKey = prescriptionDir + "/" + fileName.substring(0, fileName.lastIndexOf(".")) + fileName.substring(fileName.lastIndexOf("."));
        // 上传 阿里云 oss
        AliCloudOssUtil.putOSSObject(null, ossKey, localFile);

        DtPrescriptionTemplateManageModel model = new DtPrescriptionTemplateManageModel();
        model.setName(templateName);
        model.setTemplateSign("-1");
        model.setInstitutionId(healthManageId);
        model.setTemplatePicUrl(ossKey);
        model.setUploaderId(account.getSupervisorId());
        model.setUploaderName(account.getLoginUser());
        model.setUploadTm(new Date());
        dtHealthManageInstitutionService.savePrescriptionTemplate(model);
        return map;
    }
}